using System;
using UnityEngine;

namespace Gj
{
    public class ScreenHandleItemHelper : NodeHelper
    {
        public string name;
        public Camera camera;
        public float maxScale = 2f;
        public float minScale = 0.1f;
        public float scaleSpeed = 0.1f;
        public float speed = 10f;
        public bool invert;
        private bool allow;
        private Vector2 deltaPos = Vector2.zero;
        private float moveTime;
        private bool moving;
        private Vector2 oldPosition = Vector2.zero;

        private Touch oldTouch1; //上次触摸点1(手指1)
        private Touch oldTouch2; //上次触摸点2(手指2)
        private readonly float pre = 10;
        private float waitTime = 1;

        protected override BindDataType bindDataType => BindDataType.Bool;

        // Update is called once per frame
        private void Update()
        {
            if (!Input.GetMouseButton(0) && Input.touchCount == 0)
            {
                if (Time.time < moveTime + waitTime)
                {
                    deltaPos = new Vector2(deltaPos.x - deltaPos.x / pre / waitTime,
                        deltaPos.y - deltaPos.y / pre / waitTime);
                    transform.Rotate(deltaPos.y, deltaPos.x * -1, 0, Space.World);
                }
                else if (Time.time > moveTime + waitTime && moving)
                {
                    moving = false;
                    Emit(UIEvent.End);
                }
            }

            if (!allow) return;

            if (Input.GetMouseButtonDown(0))
            {
                var ray = camera.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;

                if (Physics.Raycast(ray, out hit))
                {
                    if (hit.transform.parent.name != name) return;
                    moving = true;
                    oldPosition = Vector2.zero;
                    Emit(UIEvent.Start);
                }
            }

            //鼠标点击， 水平上下旋转
            if (moving && Input.GetMouseButton(0))
            {
                Vector2 newPosition = Input.mousePosition;
                if (oldPosition != Vector2.zero)
                {
                    deltaPos = newPosition - oldPosition;
                    transform.Rotate(deltaPos.y, deltaPos.x * -1, 0, Space.World);
                    waitTime = (Math.Abs(deltaPos.x) + Math.Abs(deltaPos.y)) / 4 / speed;
                    moveTime = Time.time;
                }

                oldPosition = newPosition;
            }

            if (Input.mouseScrollDelta != Vector2.zero)
            {
                var _scale = transform.localScale.x + Input.mouseScrollDelta.y * scaleSpeed;
                if (_scale > maxScale || _scale < minScale) return;
                transform.localScale = new Vector3(_scale, _scale, _scale);
            }

            //没有触摸
            if (Input.touchCount <= 0) return;

            if (Input.GetTouch(0).phase == TouchPhase.Began)
            {
                var ray = camera.ScreenPointToRay(Input.GetTouch(0).position);
                RaycastHit hit;

                if (Physics.Raycast(ray, out hit))
                {
                    if (hit.transform.parent != transform) return;
                    moving = true;
                    Emit(UIEvent.Start);
                }
            }

            //单点触摸， 水平上下旋转
            if (moving && 1 == Input.touchCount)
            {
                deltaPos = Input.GetTouch(0).deltaPosition;
                transform.Rotate(deltaPos.y, deltaPos.x * -1, 0, Space.World);
                waitTime = (Math.Abs(deltaPos.x) + Math.Abs(deltaPos.y)) / 4 / speed;
                moveTime = Time.time;
            }

            //多点触摸, 放大缩小
            var newTouch1 = Input.GetTouch(0);
            var newTouch2 = Input.GetTouch(1);

            //第2点刚开始接触屏幕, 只记录，不做处理
            if (newTouch2.phase == TouchPhase.Began)
            {
                oldTouch2 = newTouch2;
                oldTouch1 = newTouch1;
                return;
            }

            //计算老的两点距离和新的两点间距离，变大要放大模型，变小要缩放模型
            var oldDistance = Vector2.Distance(oldTouch1.position, oldTouch2.position);
            var newDistance = Vector2.Distance(newTouch1.position, newTouch2.position);

            //两个距离之差，为正表示放大手势， 为负表示缩小手势
            var offset = newDistance - oldDistance;

            //放大因子， 一个像素按 0.01倍来算(100可调整)
            var scaleFactor = offset / 100f;
            var localScale = transform.localScale;
            var scale = new Vector3(localScale.x + scaleFactor,
                localScale.y + scaleFactor,
                localScale.z + scaleFactor);

            //最小缩放到 0.3 倍
            if (scale.x > 0.3f && scale.y > 0.3f && scale.z > 0.3f) transform.localScale = scale;

            //记住最新的触摸点，下次使用
            oldTouch1 = newTouch1;
            oldTouch2 = newTouch2;
        }

        protected override void BindData(bool b)
        {
            allow = invert ? !b : b;
        }
    }
}